﻿using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

using iStudio.Structure.Engine;
using iStudio.Structure.Wave;
using iStudio.View;
using iStudio.View.Dialog;

namespace iStudio
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override void OnStartup (StartupEventArgs e)
        {
            try
            {
                SafeObservableStatic.Dispatcher = Current.Dispatcher;

                Splash splash = new Splash ();
                splash.Show ();

                bool isSuccessful = true;

                splash.Dispatcher.UnhandledException += SplashDispatcherException;

                //
                // Setup dispatcher
                //

                Task startupTask = new Task (() =>
                {
                    for (int i = 0; i < 3; i++)
                    {
                        switch (i)
                        {
                            case 0:
                                splash.Dispatcher.BeginInvoke ((Action) (() =>
                                                                         {
                                                                            splash.Message = "Registering globals ...";
                                                                            Loader.Loader.RegisterGlobals ();
                                                                        }));

                                break;

                            case 1:
                                splash.Dispatcher.BeginInvoke ((Action) (() =>
                                                                        {
                                                                            try
                                                                            {
                                                                                splash.Message = "Loading plugins ...";
                                                                                Loader.Loader.LoadSystem ();
                                                                            }
                                                                            catch (System.Exception easd)
                                                                            {
                                                                                SplashException (easd.Message);
                                                                                isSuccessful = false;
                                                                            }
                                                                        }));


                                break;
                            case 2:
                                splash.Dispatcher.BeginInvoke ((Action) (() => splash.Message = "Rendering window ..."));
                                break;
                        }

                        Thread.Sleep (100);
                    }
                });

                startupTask.ContinueWith (t =>
                {
                    if (isSuccessful == false)
                    {
                        Alert.Show("There was an error loading the plugins. The interface will still work, but with limited functionality.", "There was a problem due to loading one of the plugins.", "Error loading plugins");
        
                    }

                    MainWindow mainWindow = new MainWindow ();

                    //
                    // When main windows is loaded close splash screen
                    //

                    mainWindow.Loaded += (sender, args) => splash.Close ();

                    MainWindow = mainWindow;

                    mainWindow.Show ();
                }, TaskScheduler.FromCurrentSynchronizationContext ());

                startupTask.Start();
            }
            catch (System.Exception ex)
            {
                //
                // Kill the audio engine
                //
                try
                {
                    AudioEngine.Instance.Stop ();
                    AudioEngine.Instance.Dispose ();
                }
                // ReSharper disable EmptyGeneralCatchClause
                catch
                // ReSharper restore EmptyGeneralCatchClause
                {
                }

                //
                // Display alert box
                //

                Alert.Show ("", ex.ToString (), "");

                Current.Shutdown (2);
            }
        }

        private void SplashException(string msg)
        {
            //Alert.Show("There was an error loading the plugins. The interface will still work, but with limited functionality.", msg, "Error loading plugins");
        
        }

        private void SplashDispatcherException (object sender, DispatcherUnhandledExceptionEventArgs dispatcherUnhandledExceptionEventArgs)
        {
            Alert.Show ("There was an error loading the plugins. The interface will still work, but with limited functionality.", dispatcherUnhandledExceptionEventArgs.Exception.Message, "Error loading plugins");
        }
    }
}